package com.emmy.walnut.view;

import android.graphics.Color;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.TextView;

import com.emmy.walnut.R;
import com.emmy.walnut.adapter.ItemDetailAdapter;
import com.emmy.walnut.constant.AppConstant;
import com.emmy.walnut.custom.HourAxisValueFormatter;
import com.emmy.walnut.custom.MonthValueFormatter;
import com.emmy.walnut.custom.MyMarkerView;
import com.emmy.walnut.custom.WeekValueFormatter;
import com.emmy.walnut.custom.YearValueFormatter;
import com.emmy.walnut.model.Record;
import com.emmy.walnut.presenter.SingleClassDetailPresenter;
import com.emmy.walnut.presenter.iface.SingleClassDetailPIface;
import com.emmy.walnut.util.TimeStampUtil;
import com.emmy.walnut.view.iface.SingleClassDetailIface;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.github.mikephil.charting.utils.MPPointF;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class SingleClassDetailActivity extends BaseActivity implements
        SingleClassDetailIface, OnChartValueSelectedListener {

    private BarChart barChart;
    private XAxis xAxis;
    private YAxis yLeftAxis;
    private WeekValueFormatter weekValueFormatter;
    private MonthValueFormatter monthValueFormatter;
    private YearValueFormatter yearValueFormatter;
    private HourAxisValueFormatter hourAxisValueFormatter;

    private Spinner spinner;
    private ArrayAdapter arrayAdapter;
    private ItemDetailAdapter itemDetailAdapter;

    private RecyclerView recyclerView;

    private final RectF onValueSelectedRectF = new RectF();

    private long currentTimePeriod;
    private long startTimeStamp;
    private long endTimeStamp;
    private String labelName;

    private RadioGroup radioGroup;
    private TextView timePeriod;
    private ImageButton forward;
    private ImageButton back;
    private ImageButton problemButton;

    private RadioButton day;
    private RadioButton week;

    protected Typeface tfLight;

    private static final String TAG = "SingleClassDetailActivity";

    private List<Record> records;

    private SimpleDateFormat weekFormat = new SimpleDateFormat("MM月dd日");
    private SimpleDateFormat monthFormat = new SimpleDateFormat("MM月 yyyy年");
    private SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy年");

    private SingleClassDetailPIface singleClassDetailPIface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_single_class_detail);
        labelName = AppConstant.activities.
                get(getIntent().getIntExtra("index", -1)).getLabelName();
        init();
    }

    private void init(){
        currentTimePeriod = System.currentTimeMillis();
        singleClassDetailPIface = new SingleClassDetailPresenter(this);

        timePeriod = findViewById(R.id.timePeriod);

        radioGroup = findViewById(R.id.radioGroup);
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                updateTimePeriod();
            }
        });

        forward = findViewById(R.id.forwardPeriod);
        back = findViewById(R.id.backPeriod);

        forward.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (radioGroup.getCheckedRadioButtonId()){
                    case R.id.day:
                        currentTimePeriod += 86400000;
                        break;
                    case R.id.week:
                        currentTimePeriod += 604800000;
                        break;
                    case R.id.month:
                        currentTimePeriod = TimeStampUtil.getMonthEndTime(currentTimePeriod)+1;
                        break;
                    case R.id.year:
                        currentTimePeriod = TimeStampUtil.getYearEndTime(currentTimePeriod)+1;
                        break;
                }
                updateTimePeriod();
            }
        });

        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (radioGroup.getCheckedRadioButtonId()){
                    case R.id.day:
                        currentTimePeriod -= 86400000;
                        break;
                    case R.id.week:
                        currentTimePeriod -= 604800000;
                        break;
                    case R.id.month:
                        currentTimePeriod = TimeStampUtil.getMonthStartTime(currentTimePeriod)-1;
                        break;
                    case R.id.year:
                        currentTimePeriod = TimeStampUtil.getYearStartTime(currentTimePeriod)-1;
                        break;
                }
                updateTimePeriod();
            }
        });

        problemButton = findViewById(R.id.problem_image_button);
        problemButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                View popupWindowView = LayoutInflater.from(SingleClassDetailActivity.this).inflate(R.layout.popup_hint_layout,
                        null);
                TextView hintTextView = popupWindowView.findViewById(R.id.hint);
                PopupWindow popupWindow = new PopupWindow(popupWindowView,
                        ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,
                        false);
                popupWindow.setOutsideTouchable(true);
                if (spinner.getSelectedItemPosition()==0){
                    hintTextView.setText("点击柱状图可以看到详细数据\n柱状图中的数据为四舍五入至小数点后两位\n单次小于36s的数据将不显示在柱状图中\n在具体条目中看到所有条目和精确时间");
                    popupWindow.showAsDropDown(problemButton);
                }else{
                }
            }
        });

        spinner = findViewById(R.id.spinner);
        arrayAdapter = ArrayAdapter.createFromResource(this, R.array.spinner,
                R.layout.item_spinner_layout);
        spinner.setAdapter(arrayAdapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                updateData(records);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        initChart();

        recyclerView = findViewById(R.id.recyclerView);
        LinearLayoutManager manager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(manager);

        day = findViewById(R.id.day);
        day.setVisibility(View.GONE);
        week = findViewById(R.id.week);
        week.setChecked(true);
        updateTimePeriod();
    }

    /**
     * 初始化图表属性
     */
    private void initChart(){
        barChart = findViewById(R.id.barChar);
        //初始化图表的横轴格式
        weekValueFormatter = new WeekValueFormatter(barChart);
        monthValueFormatter = new MonthValueFormatter(barChart);
        yearValueFormatter = new YearValueFormatter(barChart);

        //设置没有数据时的说明
        barChart.setNoDataText("当前时间段没有记录事件");
        barChart.setNoDataTextColor(R.color.black);
        //无需描述
        barChart.setDescription(null);
        barChart.setPinchZoom(false);
        //
        barChart.setOnChartValueSelectedListener(this);
        //初始化横轴、竖轴
        xAxis = barChart.getXAxis();
        //横轴位置
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        //横轴字体
        xAxis.setTypeface(tfLight);
        xAxis.setDrawGridLines(false);
        xAxis.setLabelCount(7);

        yLeftAxis = barChart.getAxisLeft();
        yLeftAxis.setTypeface(tfLight);
        yLeftAxis.setLabelCount(8, false);
        //位置在图表外
        yLeftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
        yLeftAxis.setSpaceTop(15f);
        yLeftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
        //设置显示格式
        hourAxisValueFormatter = new HourAxisValueFormatter(barChart);
        yLeftAxis.setValueFormatter(hourAxisValueFormatter);
        yLeftAxis.setGranularityEnabled(true);
        //设置坐标轴最小间隔
        yLeftAxis.setGranularity(0.01f);

        //不显示右边竖轴
        barChart.getAxisRight().setEnabled(false);

        //设置图表偏移
        barChart.setExtraOffsets(30, 50, 30, 50);

        //设置MarkerView
        MarkerView mv = new MyMarkerView(this, hourAxisValueFormatter);
        mv.setChartView(barChart); // For bounds control
        barChart.setMarker(mv); // Set the marker to the chart

        Legend legend = barChart.getLegend();
        //设置图例的gravity
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
        //设置图例的方向
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        legend.setDrawInside(false);
        //设置图例Space
        legend.setXEntrySpace(7f);
        legend.setYEntrySpace(0f);
        //设置图例偏移
        legend.setYOffset(20f);
    }

    private void updateTimePeriod(){
        switch (radioGroup.getCheckedRadioButtonId()){
            case R.id.week:
                startTimeStamp = TimeStampUtil.getWeekStartTime(currentTimePeriod);
                endTimeStamp = TimeStampUtil.getWeekEndTime(currentTimePeriod);
                timePeriod.setText(String.format("%s-%s", weekFormat.format(new Date(TimeStampUtil.getWeekStartTime(currentTimePeriod))),
                        weekFormat.format(new Date(TimeStampUtil.getWeekEndTime(currentTimePeriod)))));
                xAxis.setValueFormatter(weekValueFormatter);
                break;
            case R.id.month:
                startTimeStamp = TimeStampUtil.getMonthStartTime(currentTimePeriod);
                endTimeStamp = TimeStampUtil.getMonthEndTime(currentTimePeriod);
                timePeriod.setText(monthFormat.format(new Date(currentTimePeriod)));
                xAxis.setValueFormatter(monthValueFormatter);
                break;
            case R.id.year:
                startTimeStamp = TimeStampUtil.getYearStartTime(currentTimePeriod);
                endTimeStamp = TimeStampUtil.getYearEndTime(currentTimePeriod);
                timePeriod.setText(yearFormat.format(new Date(currentTimePeriod)));
                xAxis.setValueFormatter(yearValueFormatter);
                break;
        }
        singleClassDetailPIface.queryRecordWithPeriod(labelName, startTimeStamp, endTimeStamp);
    }

    /**
     * 更新数据
     * @param data 数据
     */
    @Override
    public void updateData(List<Record> data) {
        if (data==null||data.isEmpty()){
            barChart.clear();
            return;
        }
        records = data;
        switch (spinner.getSelectedItemPosition()){
            case 0:
                barChart.setVisibility(View.VISIBLE);
                recyclerView.setVisibility(View.GONE);
                updateBarData(data);
                break;
            case 1:
                barChart.setVisibility(View.GONE);
                recyclerView.setVisibility(View.VISIBLE);
                updateList(data);
                break;
            default:
                break;
        }
    }

    /**
     * 更新列表
     * @param records 数据
     */
    private void updateList(List<Record> records){
        itemDetailAdapter = new ItemDetailAdapter(this, records);
        recyclerView.setAdapter(itemDetailAdapter);
    }

    /**
     * 更新柱状图
     * @param data 数据
     */
    private void updateBarData(List<Record> data){
        List<BarEntry> barEntries;
        barEntries = handleBarEntry(radioGroup.getCheckedRadioButtonId(), data);
        BarDataSet barDataSet = new BarDataSet(barEntries, labelName);
        //在柱形上方不显示数据
        barDataSet.setDrawValues(false);
        barDataSet.setColor(Color.parseColor("#60acfc"));
        BarData barData = new BarData(barDataSet);
        barChart.setData(barData);
        //刷新数据
        barChart.invalidate();
    }

    private List<BarEntry> handleBarEntry(int period, List<Record> records){
        List<BarEntry> barEntries = new ArrayList<>();
        int index = 0;
        int num = records.size();
        //间隔时间戳
        long internalTimestamp = 0;
        long currentTempTimestamp = startTimeStamp;
        //当前时间段的时间戳
        long periodTimestamp = 0;
        //期数
        int periodNum = 0;
        int dayOfMonth = TimeStampUtil.getDaysOfMonth(currentTempTimestamp);
        //计算间隔时间和柱状图数目
        switch (period){
            case R.id.day:
            case R.id.week:
                periodNum = 7;
                internalTimestamp = 24 * 60 * 60 * 1000;
                break;
            case R.id.month:
                periodNum = dayOfMonth;
                internalTimestamp = 24 * 60 * 60 * 1000;
                break;
            case R.id.year:
                periodNum = 12;
                break;
        }
        //添加数据，
        for (int i = 0;i<periodNum;i++){
            if (period == R.id.year){
                internalTimestamp = (long)24 * 60 * 60 * 1000 * TimeStampUtil.getDaysOfMonth(currentTempTimestamp);
            }
            currentTempTimestamp += internalTimestamp;
            while(index<num){
                if((records.get(index).getEndTimestamp()-records.get(index).getStartTimestamp())
                        < 36000){
                    index++;
                    continue;
                }
                if (records.get(index).getStartTimestamp()<currentTempTimestamp){
                    periodTimestamp += (records.get(index).getEndTimestamp() -
                            records.get(index).getStartTimestamp());
                    index++;
                }else{
                    break;
                }
            }
            //增加数据
            barEntries.add(new BarEntry(i, (float) periodTimestamp/1000/60/60));
            periodTimestamp = 0;
        }
        return barEntries;
    }

    @Override
    public void onValueSelected(Entry e, Highlight h) {
        if (e==null){
            return;
        }

        RectF rectF = onValueSelectedRectF;
        barChart.getBarBounds((BarEntry) e, rectF);

        MPPointF mpPointF = barChart.getPosition(e, YAxis.AxisDependency.LEFT);
        MPPointF.recycleInstance(mpPointF);
    }

    @Override
    public void onNothingSelected() {

    }
}
